package com.kedacom.ctsp.authority.controller;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.kedacom.ctsp.authority.constant.AccessLoggerConstant;
import com.kedacom.ctsp.authority.entity.Department;
import com.kedacom.ctsp.authority.service.DepartmentService;
import com.kedacom.ctsp.authz.access.DataAccessScopeEnum;
import com.kedacom.ctsp.authz.access.DataAccessUtil;
import com.kedacom.ctsp.authz.entity.AuthPerson;
import com.kedacom.ctsp.authz.entity.AuthResource;
import com.kedacom.ctsp.authz.entity.Authentication;
import com.kedacom.ctsp.authz.exception.UnauthorizedException;
import com.kedacom.ctsp.logging.AccessLogger;
import com.kedacom.ctsp.web.controller.message.ResponseMessage;
import com.kedacom.ctsp.web.entity.TreeSupportBean;
import com.kedacom.ctsp.web.entity.param.QueryParamEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import static com.kedacom.ctsp.web.controller.message.ResponseMessage.ok;

/**
 * 登录权限相关
 *
 * @author sunchenjie
 * @create 2017-12-28 13:20
 **/
@RestController
@RequestMapping("datascope")
@AccessLogger(AccessLoggerConstant.Module.DATA_SCOPE)
@Api(tags = "rbac-authz", description = "提供基本的授权功能")
@Slf4j
public class AuthorityDataScopeController {


    @Autowired
    private DepartmentService departmentService;

    /**
     * 当前登录用户的数据权限
     *
     * @param request
     * @param resource
     * @return
     */
    @GetMapping("/me")
    @AccessLogger("当前登录用户数据权限信息")
    @ApiOperation("当前登录用户数据权限信息")
    public ResponseMessage<Map<DataAccessScopeEnum, Set<String>>> myDataScope(HttpServletRequest request, @RequestParam String resource) {
        Authentication auth = Authentication.current().orElseThrow(UnauthorizedException::new);
        return ok(getDataScope(auth, resource));
    }

    /**
     * 数据权限
     *
     * @param auth
     * @param resourceSign
     * @return
     */
    private Map<DataAccessScopeEnum, Set<String>> getDataScope(Authentication auth, String resourceSign) {

        //TODO resource 从Authentication中移除，当前controller没有地方使用，此处先注释掉
//        Optional<Set<AuthResource>> resources = auth.getResources(resourceSign);
//        if (resources.isPresent()) {
//            DataAccessScopeEnum scope = DataAccessUtil.getDataScopeByResources(resources.get());
//            Map<DataAccessScopeEnum, Set<String>> value = Maps.newHashMap();
//
//            switch (scope) {
//                default:
//                case SELF:
//                    value.put(scope, Sets.newHashSet(auth.getUser().getName()));
//                    break;
//                case DEPARTMENT:
//                    value.put(scope, Sets.newHashSet(auth.getPerson().getDeptCode()));
//                    break;
//                case CASCADE:
//                    value.put(scope, auth.getPerson().getCascadedAndChargedDeptCodes());
//                    break;
//                case ALL:
//                    value.put(scope, null);
//                    break;
//            }
//            return value;
//        }
        return null;
    }


    /**
     * 当前登录用户的部门数据权限
     *
     * @param request
     * @param resource
     * @return 返回的列表==null -> 没有权限
     * 返回的列表 empty -> 全部权限
     */
    @GetMapping("/departmentIds")
    @AccessLogger("当前登录用户数据部门权限信息")
    @ApiOperation("当前登录用户数据部门权限信息")
    public ResponseMessage<Set<String>> myDataScopeDepartmentCodes(HttpServletRequest request, @RequestParam String resource) {
        Authentication auth = Authentication.current().orElseThrow(UnauthorizedException::new);

        Map<DataAccessScopeEnum, Set<String>> dataScope = getDataScope(auth, resource);

        if (dataScope != null && CollectionUtils.isNotEmpty(dataScope.keySet())) {
            Optional<DataAccessScopeEnum> first = dataScope.keySet().stream().findFirst();

            Set<String> deptCodess = Sets.newHashSet();
            if (first.isPresent()) {
                DataAccessScopeEnum dataScopeEnum = first.get();
                switch (dataScopeEnum) {
                    // 只有自身权限
                    case SELF:
                        deptCodess.add(auth.getPerson().getDeptCode());
                        break;
                    //拥有的部门权限
                    case DEPARTMENT:
                        deptCodess.add(auth.getPerson().getDeptCode());
                        break;
                    //如果是部门级联，返回部门级联数据
                    case CASCADE:
                        if (CollectionUtils.isNotEmpty(auth.getPerson().getCascadedAndChargedDeptCodes())) {
                            deptCodess.addAll(auth.getPerson().getCascadedAndChargedDeptCodes());
                        } else {
                            return ok(null);
                        }
                        break;
                }
                return ok(deptCodess);
            }
        }
        return ok(null);
    }

    /**
     * 当前登录用户的部门数据权限
     *
     * @param request
     * @param resource
     * @return
     */
    @GetMapping("/department")
    @AccessLogger("当前登录用户数据部门权限信息")
    @ApiOperation("当前登录用户数据部门权限信息")
    public ResponseMessage<List<Department>> myDataScopeDepartment(HttpServletRequest request, @RequestParam String resource) {
        Authentication auth = Authentication.current().orElseThrow(UnauthorizedException::new);

        Map<DataAccessScopeEnum, Set<String>> dataScope = getDataScope(auth, resource);

        if (dataScope != null && CollectionUtils.isNotEmpty(dataScope.keySet())) {
            Optional<DataAccessScopeEnum> first = dataScope.keySet().stream().findFirst();

            List<Department> depts = Lists.newArrayList();
            if (first.isPresent()) {
                DataAccessScopeEnum dataScopeEnum = first.get();
                AuthPerson person = auth.getPerson();

                switch (dataScopeEnum) {
                    //如果数据权限是自身和本部门，返回本部门数据
                    default:
                    case SELF:
                    case DEPARTMENT:
                        if (person != null && person.getDeptCode() != null) {
                            Department dept = departmentService.selectByCode(person.getDeptCode());
                            depts.add(dept);
                        }
                        break;
                    //如果是部门级联，返回部门级联数据
                    case CASCADE:
                        if (person != null && person.getDeptCode() != null) {

                            Department personDept = departmentService.selectByCode(person.getDeptCode());
                            if(personDept != null){
                                depts = departmentService.selectAsTree(personDept.getId(), QueryParamEntity.empty());
                            }
                        }
                        break;
                    // 如果是所有部门
                    case ALL:
                        depts = departmentService.selectAsTree(QueryParamEntity.empty());
                        break;
                }
                ResponseMessage<List<Department>> result = ok(depts);
                result.exclude(TreeSupportBean.class, TreeSupportBean.PARENT);
                return result;
            }
        }
        return ok(null);
    }


}